﻿#include "framework.h"
#include "Const.h"
#include "Protocol.h"
#include "RegWindow.h"
#include "Resource.h"

#ifndef STRING_BUF_LEN
#define STRING_BUF_LEN 256
#endif

// 函数声明
static void RegWindow_Delete(RegWindow*);
static INT_PTR RegWindow_DoModal(RegWindow*);
static void RegWindow_OnOK(RegWindow*);
static INT_PTR CALLBACK RegWindow_Proc(HWND, UINT, WPARAM, LPARAM);

/**
 * 创建注册窗口。
 * @param parent    父窗口
 * @return 注册窗口
 */
RegWindow* New_RegWindow(HWND parent) {
    RegWindow* regWindow = (RegWindow*)calloc(1, sizeof(RegWindow));

    // 初始化数据
    regWindow->mParent = parent;
    regWindow->mPassword = (LPTSTR)calloc(1, PASSWORD_BUF_LEN * sizeof(TCHAR));
    regWindow->mUsername = (LPTSTR)calloc(1, USERNAME_BUF_LEN * sizeof(TCHAR));

    // 初始化函数
    regWindow->deleteSelf = RegWindow_Delete;
    regWindow->doModal = RegWindow_DoModal;

    return regWindow;
}

/**
 * 删除注册窗口。
 * @param regWindow 注册窗口
 */
static void RegWindow_Delete(RegWindow* regWindow) {
    free(regWindow->mUsername);
    free(regWindow->mPassword);
    regWindow->mListViewIcons->deleteSelf(regWindow->mListViewIcons);
    free(regWindow);
}

/**
 * 以模态显示窗口。
 * @param regWindow 注册窗口
 * @return 为 IDOK 表示用户单击了"确定"按钮，为 IDCANCEL 表示用户单击了"取消"按钮
 */
static INT_PTR RegWindow_DoModal(RegWindow* regWindow) {
    return DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_REG_WINDOW), 
        regWindow->mParent, RegWindow_Proc, (LPARAM)regWindow);
}

/**
 * "确定"按钮的单击响应方法。
 * @param regWindow 注册窗口
 */
static void RegWindow_OnOK(RegWindow* regWindow) {
    LPTSTR username = (LPTSTR)calloc(1, USERNAME_BUF_LEN * sizeof(TCHAR));      // 用户输入的用户名
    LPTSTR password = (LPTSTR)calloc(1, PASSWORD_BUF_LEN * sizeof(TCHAR));      // 用户输入的密码
    LPTSTR repassword = (LPTSTR)calloc(1, PASSWORD_BUF_LEN * sizeof(TCHAR));    // 用户输入的确认密码
    int itemIndex = -1;                                                         // 用户选择的头像索引
    TCHAR text[STRING_BUF_LEN] = { 0 };                                         // 提示信息

    // 检查用户名是否为空
    GetDlgItemText(regWindow->mHandle, IDC_EDIT_USERNAME, username, PASSWORD_BUF_LEN);
    if (_tcscmp(username, _T("")) == 0) {
        LoadString(NULL, IDS_USERNAME_EMPTY, text, STRING_BUF_LEN);
        MessageBox(regWindow->mHandle, text, _T(" "), MB_ICONERROR);
        SetFocus(GetDlgItem(regWindow->mHandle, IDC_EDIT_USERNAME));
        free(username);
        free(password);
        free(repassword);
        return;
    }

    // 检查密码是否为空
    GetDlgItemText(regWindow->mHandle, IDC_EDIT_PASSWORD, password, PASSWORD_BUF_LEN);
    if (_tcscmp(password, _T("")) == 0) {
        LoadString(NULL, IDS_PASSWORD_EMPTY, text, STRING_BUF_LEN);
        MessageBox(regWindow->mHandle, text, _T(" "), MB_ICONERROR);
        SetFocus(GetDlgItem(regWindow->mHandle, IDC_EDIT_PASSWORD));
        free(username);
        free(password);
        free(repassword);
        return;
    }

    // 检查两次密码是否一致
    GetDlgItemText(regWindow->mHandle, IDC_EDIT_REPASSWORD, repassword, PASSWORD_BUF_LEN);
    if (_tcscmp(password, repassword) != 0) {
        LoadString(NULL, IDS_PASSWORD_NOT_EQUAL, text, STRING_BUF_LEN);
        MessageBox(regWindow->mHandle, text, _T(" "), MB_ICONERROR);
        SetFocus(GetDlgItem(regWindow->mHandle, IDC_EDIT_PASSWORD));
        free(username);
        free(password);
        free(repassword);
        return;
    }

    // 检查头像索引
    itemIndex = ListView_GetNextItem(regWindow->mListViewIcons->mHandle, -1, LVIS_SELECTED);
    if (itemIndex == -1) {
        LoadString(NULL, IDS_ICON_NOT_SELECT, text, STRING_BUF_LEN);
        MessageBox(regWindow->mHandle, text, _T(" "), MB_ICONWARNING);
        SetFocus(GetDlgItem(regWindow->mHandle, IDC_LIST_VIEW_ICONS));
        return;
    }

    // 保存用户信息
    _tcscpy_s(regWindow->mUsername, USERNAME_BUF_LEN, username);
    _tcscpy_s(regWindow->mPassword, PASSWORD_BUF_LEN, password);
    regWindow->mIconIndex = itemIndex;

    // 关闭窗口
    EndDialog(regWindow->mHandle, IDOK);

    free(username);
    free(password);
    free(repassword);
}


/**
 * 窗口过程函数。
 * @param window    窗口
 * @param message   事件标识
 * @param wParam    事件相关信息
 * @param lParam    事件相关信息
 * @return 事件在此被处理则返回 TRUE，否则返回 FALSE
 */
static INT_PTR CALLBACK RegWindow_Proc(HWND window, UINT message, WPARAM wParam, LPARAM lParam) {
    RegWindow* regWindow = (RegWindow*)GetWindowLongPtr(window, GWLP_USERDATA);
    WORD id = LOWORD(wParam);
    int i = 0;

    switch (message) {
        case WM_COMMAND:
            switch (id) {
                case IDCANCEL:
                    EndDialog(regWindow->mHandle, IDCANCEL);
                    break;
                case IDOK:
                    RegWindow_OnOK(regWindow);
                    break;
            }
            return TRUE;
        case WM_INITDIALOG:
            regWindow = (RegWindow*)lParam;
            regWindow->mHandle = window;
            SetWindowLongPtr(regWindow->mHandle, GWLP_USERDATA, (LONG_PTR)regWindow);

            // 创建列表控件
            regWindow->mListViewIcons = New_UserListView(IDC_LIST_VIEW_ICONS, window);

            // 为列表控件添加图标
            for (i = 0; i < ICON_COUNT; i++) {
                regWindow->mListViewIcons->addItem(regWindow->mListViewIcons, _T(""), i, TRUE);
            }

            // 设置最大用户名长度和最大密码长度
            SendMessage(GetDlgItem(regWindow->mHandle, IDC_EDIT_USERNAME), EM_SETLIMITTEXT, MAX_USERNAME_LEN, 0);
            SendMessage(GetDlgItem(regWindow->mHandle, IDC_EDIT_PASSWORD), EM_SETLIMITTEXT, MAX_PASSWORD_LEN, 0);
            SendMessage(GetDlgItem(regWindow->mHandle, IDC_EDIT_REPASSWORD), EM_SETLIMITTEXT, MAX_PASSWORD_LEN, 0);
            return TRUE;
    }
    return FALSE;
}
